package com.witframework.util;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.sql.Connection;
import java.util.Collection;
import java.util.Vector;


/**
 * 数据库连接引用监控，实现了在引用数据库连接的对象被垃圾收回前释放未关闭的连接。 注意该对象并不是用来管理数据库连接的，是用来解决数据库连接资源泄漏。
 * 使用方法： ConnectionReferenceMonitor.track(Connection conn,Object
 * marker);//marker 调用连接的对象
 *
 * @author wuxinyang
 *
 */
public class ConnectionReferenceMonitor {

	private static ReferenceQueue q = new ReferenceQueue();

	private static Collection trackers = new Vector();

	private static Thread reaper = null;

	private ConnectionReferenceMonitor() {
	}

	private static class MonitoringProcess implements Runnable{
		public void run() {
			while(!trackers.isEmpty()){
				Tracker tracker = null;
				try {
					tracker = (Tracker) q.remove();
					tracker.close();
					tracker.clear();
				} catch (Exception _) {
					continue;
				}
				trackers.remove(tracker);
			}
		}
	}

	/**
	 * 加入要监控的对象引用
	 *
	 * @param conn
	 *            java.sql.Connection 数据库连接对象
	 * @param marker
	 *            marker 引用数据库连接的对象
	 */
	public static void track(Connection conn, Object marker) {
		trackers.add(new Tracker(conn, marker, q));
		if(reaper==null){
			reaper = new Thread(new MonitoringProcess(),ConnectionReferenceMonitor.class.getName());
			reaper.setPriority(Thread.MAX_PRIORITY);
			reaper.setDaemon(true);
			reaper.start();
		}
	}

	/**
	 * 获取正在监控的连接数量
	 *
	 * @return int
	 */
	public static int getTrackCount() {
		return trackers.size();
	}

	private static class Tracker extends PhantomReference {
		private Connection conn = null;

		public Tracker(Connection conn, Object marker, ReferenceQueue q) {
			super(marker, q);
			this.conn = conn;
		}

		public void close() throws Exception {
			if (conn != null&&!conn.isClosed()){
				try {
					conn.commit();
				} catch (Exception e) {
				}
				try {
					conn.close();
				} catch (Exception e) {
				}
				System.out.println("ConnectionMonitor:释放连接.正在监控的连接数量:"+trackers.size());
			}
		}
	}

}
